﻿using System;
using System.Collections;
using System.IO;
using System.Web;

namespace ElectronicCommerce.Framework.Web.UI.GeneratedImage.ImageStore
{
    public class DiskImageStore : IImageStore
    {
        private Hashtable _fileLocks = new Hashtable();
        private static DiskImageStore s_instance;
        private static object s_instanceLock = new object();

        internal static IImageStore Instance
        {
            get
            {
                if (s_instance == null)
                {
                    lock (s_instanceLock)
                    {
                        if (s_instance == null)
                        {
                            s_instance = new DiskImageStore();
                        }
                    }
                }
                return s_instance;
            }
        }

        #region IImageStore Members

        /// <summary>
        /// 添加一张图片
        /// </summary>
        /// <param name="id"></param>
        /// <param name="data"></param>
        public void Add(string filePath, byte[] data)
        {
            lock (GetFileLockObject(filePath))
            {
                try
                {
                    if (!Directory.Exists(Path.GetDirectoryName(filePath)))
                        Directory.CreateDirectory(Path.GetDirectoryName(filePath));

                    File.WriteAllBytes(filePath, data);
                }
                catch (Exception)
                {
                    // REVIEW for now ignore any write problems
                }
            }
        }

        /// <summary>
        /// 如果一张图片已经存在则直接输出
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="response"></param>
        /// <returns></returns>
        public bool TryTransmitIfContains(string filePath, HttpResponseBase response)
        {
            lock (GetFileLockObject(filePath))
            {
                if (File.Exists(filePath))
                {
                    response.TransmitFile(filePath);
                    return true;
                }
                else
                {
                    return false;
                }
            }
        }

        #endregion

        private object GetFileLockObject(string filePath)
        {
            object lockObject = _fileLocks[filePath];

            if (lockObject == null)
            {
                // lock on the hashtable to prevent other writers
                lock (_fileLocks)
                {
                    lockObject = new object();
                    _fileLocks[filePath] = lockObject;
                }
            }

            return lockObject;
        }

        private void DiscardFileLockObject(string filePath)
        {
            // lock on hashtable to prevent other writers
            lock (_fileLocks)
            {
                _fileLocks.Remove(filePath);
            }
        }
    }
}
